import 'dart:io';

import 'package:jm_flutter_common/jm_flutter_common.dart';

enum AppFileType {
  image,
  video,
  audio,
  document,
  other,
}

class AppFileDesc {
  final String name;
  final String path;
  final bool isDir;
  final AppFileType fileType;
  final int size;
  final int duration;

  /// The create time in unix timestamp of the asset.
  final int? createDateSecond;

  /// The create time of the asset in [DateTime].
  DateTime get createDateTime {
    final int value = createDateSecond ?? 0;
    return DateTime.fromMillisecondsSinceEpoch(value * 1000);
  }

  /// The modified time in unix timestamp of the asset.
  final int? modifiedDateSecond;

  /// The modified time of the asset in [DateTime].
  DateTime get modifiedDateTime {
    final int value = modifiedDateSecond ?? 0;
    return DateTime.fromMillisecondsSinceEpoch(value * 1000);
  }

  bool get isImage => fileType == AppFileType.image;
  bool get isVideo => fileType == AppFileType.video;
  bool get isAudio => fileType == AppFileType.audio;
  bool get isDocument => fileType == AppFileType.document;

  Duration get videoDuration => Duration(seconds: duration);

  bool get hiddenFile => name.startsWith(".");

  String get sizeStr => size.toFileSize();

  String get createTimeStr =>
      createDateSecond == 0 ? "" : createDateTime.normalStrNotSecond;

  String get extension => name.split('.').last.toLowerCase();

  AppFileDesc({
    required this.name,
    this.path = "",
    this.fileType = AppFileType.other,
    this.size = 0,
    this.duration = 0,
    this.createDateSecond,
    this.modifiedDateSecond,
    this.isDir = false,
  });

  factory AppFileDesc.formFileSystemEntity(FileSystemEntity fileSystemEntity,
      {String? dirPath}) {
    String name = "";

    if (dirPath != null) {
      name = fileSystemEntity.path.replaceFirst(dirPath, "");
    } else {
      name = fileSystemEntity.path.split('/').last;
    }
    final extension = name.split('.').last.toLowerCase();
    AppFileType _fileType = extensionToFileType(extension);
    return AppFileDesc(
        name: name,
        path: fileSystemEntity.path,
        fileType: _fileType,
        size: fileSystemEntity.statSync().size,
        createDateSecond:
            fileSystemEntity.statSync().changed.millisecondsSinceEpoch ~/ 1000,
        isDir:
            fileSystemEntity.statSync().type == FileSystemEntityType.directory);
  }

  @override
  String toString() {
    // TODO: implement toString
    return "name:$name,path:$path,fileType:$fileType,size:$size,duration:$duration,createDateSecond:$createDateSecond,modifiedDateSecond:$modifiedDateSecond,isDir:$isDir";
  }

  toMap() {
    return {
      "name": name,
      "path": path,
      //"fileType":fileType.index,
      "size": size,
      //"duration":duration,
      "createDateSecond": createDateSecond,
      "modifiedDateSecond": modifiedDateSecond,
      "isDir": isDir,
    };
  }

  static AppFileType extensionToFileType(String extension) {
    switch (extension) {
      case "mp4":
      case "mov":
      case "mkv":
      case "avi":
      case "flv":
        return AppFileType.video;
      case "wav":
      case "mp3":
      case "m4a":
        return AppFileType.audio;
      case "jpg":
      case "png":
      case "jpeg":
      case "gif":
      case "webp":
      case "heic":
        return AppFileType.image;
      case "pdf":
      case "doc":
      case "docx":
      case "xls":
      case "xlsx":
      case "ppt":
      case "pptx":
      case "txt":
      case "html":
      case "htm":
      case "xml":
      case "json":
      case "bak":
      case "gs":
        return AppFileType.document;
      default:
        return AppFileType.other;
    }
  }
}
